#include "attendservice.h"

QJsonArray AttendService::getAttendList() {
    QJsonArray array;
    QSqlQuery query = dbManager->execQuery("SELECT * FROM attend ORDER BY time DESC");

    while (query.next()) {
        QJsonObject obj;
        obj["id"] = query.value("id").toInt();
        obj["userId"] = query.value("user_id").toString();
        obj["time"] = query.value("time").toString();
        array.append(obj);
    }
    return array;
}

bool AttendService::addOrUpdateAttendRecord(
        const QString& employeeId,
        const QString& recordDate,
        const QString& time,
        const QString& type,
        const QString& status,
        const QTime& workStart,
        const QTime& workEnd,
        const QTime& splitTime)
{
    // 参数校验
    if (employeeId.isEmpty() || recordDate.isEmpty() || time.isEmpty() || type.isEmpty() || status.isEmpty()) {
        qWarning() << "[AttendService] Parameters cannot be empty";
        return false;
    }

    // 解析打卡时间（确保格式正确）
    QTime checkTime = QTime::fromString(time, "HH:mm:ss");
    if (!checkTime.isValid()) {
        qWarning() << "[AttendService] Invalid time format:" << time;
        return false;
    }

    // 计算迟到/早退分钟数
    int lateMinutes = 0;
    int earlyMinutes = 0;

    if (type == "in") {
        // 签到：仅当状态为"迟到"时计算迟到分钟数（上班时间 → 打卡时间）
        if (status == "迟到" && checkTime > workStart) {
            lateMinutes = workStart.secsTo(checkTime) / 60; // 秒转分钟
            lateMinutes = qMax(lateMinutes, 0); // 确保非负
        }
        // 状态为"正常"或"缺勤"时，迟到分钟数为0
    } else if (type == "out") {
        // 签退：仅当状态为"早退"时计算早退分钟数（打卡时间 → 下班时间）
        if (status == "早退" && checkTime < workEnd) {
            earlyMinutes = checkTime.secsTo(workEnd) / 60; // 秒转分钟
            earlyMinutes = qMax(earlyMinutes, 0); // 确保非负
        }
        // 状态为"正常"或"缺勤"时，早退分钟数为0
    } else {
        qWarning() << "[AttendService] Invalid check type:" << type;
        return false;
    }

    // 检查当天是否已有考勤记录
    QString checkSql = "SELECT id FROM attend WHERE employee_id = :employee_id AND record_date = :record_date";
    QSqlQuery checkQuery = dbManager->execQueryWithParams(checkSql, [&](QSqlQuery& q) {
            q.bindValue(":employee_id", employeeId);
            q.bindValue(":record_date", recordDate);
            return true;
});

    if (checkQuery.next()) {
        // 已有记录 → 更新对应字段（签到/签退分开更新，不覆盖已有数据）
        QString updateSql;
        if (type == "in") {
            // 更新签到相关字段：签到时间、迟到分钟数、签到状态
            updateSql = R"(
                        UPDATE attend
                        SET sign_in_time = :time,
                        late_minutes = :late,
                        sign_in_status = :status
                        WHERE employee_id = :employee_id AND record_date = :record_date
                        )";
        } else {
            // 更新签退相关字段：签退时间、早退分钟数、签退状态
            updateSql = R"(
                        UPDATE attend
                        SET sign_out_time = :time,
                        early_minutes = :early,
                        sign_out_status = :status
                        WHERE employee_id = :employee_id AND record_date = :record_date
                        )";
        }

        return dbManager->execNonQueryWithParams(updateSql, [&](QSqlQuery& q) {
            q.bindValue(":time", time);
            q.bindValue(":late", lateMinutes);    // 仅签到时有效
            q.bindValue(":early", earlyMinutes);  // 仅签退时有效
            q.bindValue(":status", status);       // 签到/签退状态
            q.bindValue(":employee_id", employeeId);
            q.bindValue(":record_date", recordDate);
            return true;
        });
    } else {
        // 无记录 → 插入新记录（初始化未打卡字段为NULL，状态为对应值）
        QString insertSql = R"(
                            INSERT INTO attend (
                            employee_id, record_date,
                            sign_in_time, late_minutes, sign_in_status,
                            sign_out_time, early_minutes, sign_out_status
                            ) VALUES (
                            :employee_id, :record_date,
                            :sign_in, :late, :sign_in_status,
                            :sign_out, :early, :sign_out_status
                            )
                            )";

        return dbManager->execNonQueryWithParams(insertSql, [&](QSqlQuery& q) {
            q.bindValue(":employee_id", employeeId);
            q.bindValue(":record_date", recordDate);

            // 签到相关字段（仅签到时赋值，签退时为NULL）
            if (type == "in") {
                q.bindValue(":sign_in", time);
                q.bindValue(":late", lateMinutes);
                q.bindValue(":sign_in_status", status);
                q.bindValue(":sign_out", QVariant(QVariant::String)); // 未签退
                q.bindValue(":early", 0);
                q.bindValue(":sign_out_status", "缺卡"); // 初始状态为缺卡
            }
            // 签退相关字段（仅签退时赋值，签到时为NULL）
            else {
                q.bindValue(":sign_in", QVariant(QVariant::String)); // 未签到
                q.bindValue(":late", 0);
                q.bindValue(":sign_in_status", "缺卡"); // 初始状态为缺卡
                q.bindValue(":sign_out", time);
                q.bindValue(":early", earlyMinutes);
                q.bindValue(":sign_out_status", status);
            }

            return true;
        });
    }
}

QJsonObject AttendService::getAttendStatusByEmployeeIdAndDate(const QString &employeeId, const QString &recordDate)
{
    QJsonObject status;
    QString sql = R"(
                  SELECT
                  sign_in_status, late_minutes,
                  sign_out_status, early_minutes,
                  sign_in_time, sign_out_time  -- 新增：获取打卡时间用于判断实际打卡类型
                  FROM attend
                  WHERE employee_id = :employee_id AND record_date = :record_date
                  )";

    QSqlQuery query = dbManager->execQueryWithParams(sql, [&](QSqlQuery& q) {
            q.bindValue(":employee_id", employeeId);
            q.bindValue(":record_date", recordDate);
            return true;
});

    if (query.next())
    {
        QString signInStatus = query.value("sign_in_status").toString();
        QString signOutStatus = query.value("sign_out_status").toString();
        QString signInTime = query.value("sign_in_time").toString(); // 实际签到时间
        QString signOutTime = query.value("sign_out_time").toString(); // 实际签退时间

        status["signInStatus"] = signInStatus;
        status["signOutStatus"] = signOutStatus;
        status["lateMinutes"] = query.value("late_minutes").toInt();
        status["earlyMinutes"] = query.value("early_minutes").toInt();

        // 修正：根据实际是否有签到/签退时间判断当前打卡类型
        if (!signInTime.isEmpty() && signOutTime.isEmpty()) {
            // 已签到，未签退 → 当前是签到状态
            status["checkType"] = "in";
            status["currentStatus"] = signInStatus;
        } else if (signInTime.isEmpty() && !signOutTime.isEmpty()) {
            // 未签到，已签退 → 当前是签退状态
            status["checkType"] = "out";
            status["currentStatus"] = signOutStatus;
        } else if (!signInTime.isEmpty() && !signOutTime.isEmpty()) {
            // 既签到又签退 → 根据时间判断最后一次打卡类型（可选）
            QTime inTime = QTime::fromString(signInTime, "HH:mm:ss");
            QTime outTime = QTime::fromString(signOutTime, "HH:mm:ss");
            if (inTime.isValid() && outTime.isValid() && outTime > inTime) {
                status["checkType"] = "out";
                status["currentStatus"] = signOutStatus;
            } else {
                status["checkType"] = "in";
                status["currentStatus"] = signInStatus;
            }
        } else {
            // 都未打卡 → 缺卡状态
            status["checkType"] = "";
            status["currentStatus"] = "缺卡";
        }
    }

    return status;
}

bool AttendService::isAttendRecordExists(const QString &employeeId, const QString &recordDate, const QString &checkType)
{
    // 参数校验
    if (employeeId.isEmpty() || recordDate.isEmpty() || (checkType != "in" && checkType != "out")) {
        qWarning() << "[AttendService] Invalid parameters for duplicate check:"
                   << "employeeId=" << employeeId << "recordDate=" << recordDate << "checkType=" << checkType;
        return false;
    }

    // 构造SQL查询（查询对应类型的打卡时间是否存在）
    QString sql;
    if (checkType == "in") {
        // 签到：查询 sign_in_time 是否非空
        sql = R"(
              SELECT sign_in_time
              FROM attend
              WHERE employee_id = :employee_id AND record_date = :record_date
              AND sign_in_time IS NOT NULL AND sign_in_time != ''
              )";
    } else {
        // 签退：查询 sign_out_time 是否非空
        sql = R"(
              SELECT sign_out_time
              FROM attend
              WHERE employee_id = :employee_id AND record_date = :record_date
              AND sign_out_time IS NOT NULL AND sign_out_time != ''
              )";
    }

    // 执行参数化查询）
    QSqlQuery query = dbManager->execQueryWithParams(sql, [&](QSqlQuery& q) {
            // 绑定参数（
            q.bindValue(":employee_id", employeeId);
            q.bindValue(":record_date", recordDate);
            return true; // 绑定成功
});

    // 若查询到记录，说明已打卡
    bool isDuplicate = query.next();
    if (isDuplicate) {
        QString existingTime = checkType == "in"
                ? query.value("sign_in_time").toString()
                : query.value("sign_out_time").toString();
        qDebug() << "[AttendService] Duplicate check found. Employee:" << employeeId
                 << "Date:" << recordDate << "Type:" << checkType << "Existing time:" << existingTime;
    }

    return isDuplicate;
}

QJsonArray AttendService::getAttendRecordsByEmployeeId(const QString& employeeId) {
    QJsonArray array;
    if (employeeId.isEmpty()) {
        qWarning() << "Employee ID cannot be empty";
        return array;
    }

    // 构造查询SQL（按日期倒序，最新记录在前）
    QString sql = R"(
                  SELECT * FROM attend
                  WHERE employee_id = :employee_id
                  ORDER BY record_date DESC
                  )";

    QSqlQuery query = dbManager->execQueryWithParams(sql, [&](QSqlQuery& q) {
            q.bindValue(":employee_id", employeeId);
            return true;
});

    while (query.next()) {
        QJsonObject obj;
        obj["id"] = query.value("id").toInt();
        obj["employeeId"] = query.value("employee_id").toString();
        obj["recordDate"] = query.value("record_date").toString();
        obj["signInTime"] = query.value("sign_in_time").toString();
        obj["lateMinutes"] = query.value("late_minutes").toInt();
        obj["signInStatus"] = query.value("sign_in_status").toString();
        obj["signOutTime"] = query.value("sign_out_time").toString();
        obj["earlyMinutes"] = query.value("early_minutes").toInt();
        obj["signOutStatus"] = query.value("sign_out_status").toString();
        array.append(obj);
    }
    return array;
}

bool AttendService::updateLeaveStatus(
        const QString& employeeId,
        const QString& recordDate,
        const QString& signInStatus,
        const QString& signOutStatus)
{
    // 参数校验
    if (employeeId.isEmpty() || recordDate.isEmpty() || signInStatus.isEmpty() || signOutStatus.isEmpty()) {
        qWarning() << "[AttendService] updateLeaveStatus: Parameters cannot be empty";
        return false;
    }

    // 检查是否已有该员工当天的考勤记录
    QString checkSql = "SELECT id FROM attend WHERE employee_id = :employee_id AND record_date = :record_date";
    QSqlQuery checkQuery = dbManager->execQueryWithParams(checkSql, [&](QSqlQuery& q) {
            q.bindValue(":employee_id", employeeId);
            q.bindValue(":record_date", recordDate);
            return true;
});

    if (checkQuery.next()) {
        // 已有记录：更新对应状态字段
        QString updateSql = R"(
                            UPDATE attend
                            SET sign_in_status = :sign_in_status,
                            sign_out_status = :sign_out_status,
                            sign_in_time = :sign_in_time,
                            sign_out_time = :sign_out_time,
                            late_minutes = 0,
                            early_minutes = 0
                            WHERE employee_id = :employee_id AND record_date = :record_date
                            )";

        return dbManager->execNonQueryWithParams(updateSql, [&](QSqlQuery& q) {
            q.bindValue(":sign_in_status", signInStatus);
            q.bindValue(":sign_out_status", signOutStatus);
            // 请假记录无实际打卡时间，设为NULL
            q.bindValue(":sign_in_time", QVariant(QVariant::String));
            q.bindValue(":sign_out_time", QVariant(QVariant::String));
            q.bindValue(":employee_id", employeeId);
            q.bindValue(":record_date", recordDate);
            return true;
        });
    } else {
        // 无记录：插入新记录（优化初始化逻辑）
        QString insertSql = R"(
                            INSERT INTO attend (
                            employee_id, record_date,
                            sign_in_time, late_minutes, sign_in_status,
                            sign_out_time, early_minutes, sign_out_status
                            ) VALUES (
                            :employee_id, :record_date,
                            :sign_in_time, :late, :sign_in_status,
                            :sign_out_time, :early, :sign_out_status
                            )
                            )";
        return dbManager->execNonQueryWithParams(insertSql, [&](QSqlQuery& q) {
            q.bindValue(":employee_id", employeeId);
            q.bindValue(":record_date", recordDate);

            // 请假记录无打卡时间，统一设为NULL
            q.bindValue(":sign_in_time", QVariant(QVariant::String));
            q.bindValue(":sign_out_time", QVariant(QVariant::String));

            // 迟到/早退分钟数固定为0（与addOrUpdateAttendRecord一致）
            q.bindValue(":late", 0);
            q.bindValue(":early", 0);

            // 签到/签退状态使用传入的请假状态（如“上午请假”“缺卡”等）
            q.bindValue(":sign_in_status", signInStatus);
            q.bindValue(":sign_out_status", signOutStatus);

            return true;
        });
    }
}
